<template>
    <canvas ref="canvas" class="canvas"></canvas>
</template>

<script setup>

class StarField {
    constructor(canvas) {
        this.canvas = canvas;
        this.ctx = canvas.getContext('2d');
        this.w = (canvas.width = window.innerWidth);
        this.h = (canvas.height = window.innerHeight);
        this.hue = 217;
        this.stars = [];
        this.count = 0;
        this.maxStars = 1200;
        this.animationId = null;

        this.canvas2 = document.createElement('canvas');
        this.ctx2 = this.canvas2.getContext('2d');
        this.canvas2.width = 100;
        this.canvas2.height = 100;
        this.createGradient();

        this.initStars();
    }

    createGradient() {
        const half = this.canvas2.width / 2;
        const gradient2 = this.ctx2.createRadialGradient(half, half, 0, half, half, half);
        gradient2.addColorStop(0.025, '#fff');
        gradient2.addColorStop(0.1, `hsl(${this.hue}, 61%, 33%)`);
        gradient2.addColorStop(0.25, `hsl(${this.hue}, 64%, 6%)`);
        gradient2.addColorStop(1, 'transparent');

        this.ctx2.fillStyle = gradient2;
        this.ctx2.beginPath();
        this.ctx2.arc(half, half, half, 0, Math.PI * 2);
        this.ctx2.fill();
    }

    random(min, max) {
        if (arguments.length < 2) {
            max = min;
            min = 0;
        }
        if (min > max) {
            [min, max] = [max, min];
        }
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    maxOrbit(x, y) {
        const max = Math.max(x, y);
        const diameter = Math.round(Math.sqrt(max * max + max * max));
        return diameter / 2;
    }

    createStar() {
        const orbitRadius = this.random(this.maxOrbit(this.w, this.h));
        const radius = this.random(60, orbitRadius) / 12;
        const orbitX = this.w / 2;
        const orbitY = this.h / 2;
        const timePassed = this.random(0, this.maxStars);
        const speed = this.random(orbitRadius) / 900000;
        const alpha = this.random(2, 10) / 10;

        return { orbitRadius, radius, orbitX, orbitY, timePassed, speed, alpha };
    }

    initStars() {
        for (let i = 0; i < this.maxStars; i++) {
            this.stars.push(this.createStar());
        }
    }

    drawStar(star) {
        const { orbitRadius, radius, orbitX, orbitY, timePassed, speed, alpha } = star;
        let x = Math.sin(timePassed) * orbitRadius + orbitX;
        let y = Math.cos(timePassed) * orbitRadius + orbitY;
        let twinkle = this.random(10);

        if (twinkle === 1 && star.alpha > 0) {
            star.alpha -= 0.05;
        } else if (twinkle === 2 && star.alpha < 1) {
            star.alpha += 0.05;
        }

        this.ctx.globalAlpha = alpha;
        this.ctx.drawImage(this.canvas2, x - radius / 2, y - radius / 2, radius, radius);
        star.timePassed += speed;
    }

    animate() {
        this.ctx.globalCompositeOperation = 'source-over';
        this.ctx.globalAlpha = 0.8;
        this.ctx.fillStyle = `hsla(${this.hue}, 64%, 6%, 1)`;
        this.ctx.fillRect(0, 0, this.w, this.h);

        this.ctx.globalCompositeOperation = 'lighter';
        for (const star of this.stars) {
            this.drawStar(star);
        }

        this.animationId = requestAnimationFrame(() => this.animate());
    }

    resize() {
        this.w = this.canvas.width = window.innerWidth;
        this.h = this.canvas.height = window.innerHeight;
        this.stars = [];
        this.initStars();
    }

    start() {
        this.animate();
        window.addEventListener('resize', () => this.resize());
    }

    stop() {
        cancelAnimationFrame(this.animationId);
        window.removeEventListener('resize', () => this.resize());
    }
}

const canvas = ref(null);
let starField = null;

onMounted(() => {
    starField = new StarField(canvas.value);
    starField.start();
});

onBeforeUnmount(() => {
    if (starField) {
        starField.stop();
    }
});
</script>

<style>
body {
    margin: 0;
    overflow: hidden;
}

.canvas {
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    opacity: 0.5;
    width: 100%;
    height: 100%;
    background: #060e1b;
    z-index: -999;
}
</style>